(ns scripts.script
  (:use util.file
        [util.utils :only [get-resource]])
  (:require clojure.string))

(defn- ns-main [ns]
  (when-let [ns (find-ns ns)]
    (when-let [main (get (ns-interns ns) '-main)]
      (apply main *command-line-args*))))

(defn find-file [ns]
  (let [base (-> (str ns) (clojure.string/replace #"\." "/") (clojure.string/replace #"-" "_"))]
    (or (get-resource (str base ".clj"))
      (get-resource (str base "__init.class")))))

(defn execute-as-file [script]
  (when (and (is-file? script) (= (file-extension script) ".clj"))
    (load-file script)
    (let [ns (or (second (re-find #"\(ns\s+([^\s)]+)" (slurp script))) "user")]
      (ns-main (symbol ns))) ; TODO: figure out a better way
    :file))

(defn execute-as-ns [script]
  (when (find-file script)
    (let [ns (symbol script)]
      (require ns)
      (ns-main ns)) ; XXX: sometimes ns is incorrect or non-declared, how to find main?
    :ns))

(defn execute-as-script-ns [script]
  (when (execute-as-ns (str "scripts." script))
    :script))

(defn execute-as-ns-surely [script]
  (let [ns (symbol script)]
    (require ns)
    (ns-main ns))
  :ns)

(defn -main [& [script & args]]
  (if script
    (binding [*command-line-args* args]
      (or (execute-as-file script)
          (execute-as-ns script)
          (execute-as-script-ns script)
          (throw (Exception. (str script " is not a file, nor a namespace")))))
    (println "Usage: mekit-script script-name")))

